package com.nowcoder.community.service.impl;

import co.elastic.clients.elasticsearch._types.SortOptions;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import com.nowcoder.community.elasticsearch.DiscussPostRepository;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.service.ElasticsearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.HighlightQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author szq
 * @create 2023-02-12 3:13
 * @description 社区搜索服务
 */
@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {

    @Autowired
    private DiscussPostRepository discussPostRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    // 新增
    @Override
    public void saveDiscussPost(DiscussPost post) {
        discussPostRepository.save(post);
    }

    // 删除
    @Override
    public void deleteDiscussPost(int id) {
        discussPostRepository.deleteById(id);
    }

    /**
     * 搜索
     * @param keyword 关键词
     * @param current 页码
     * @param limit 行数
     * @return 搜索到的帖子和数量 map
     */
    @Override
    public Map<String, Object> searchDiscussPost(String keyword, int current, int limit) {
        Map<String, Object> map = new HashMap<>();
        List<HighlightField> list = new ArrayList<>();
        list.add(new HighlightField("title"));
        list.add(new HighlightField("content"));
        Query searchQuery = NativeQuery.builder()
                .withQuery(QueryBuilders.queryString(fn -> fn.query(keyword).fields("title", "content")))
                .withSort(SortOptions.of(fn -> fn.field(q -> q.field("type").order(SortOrder.Desc))))
                .withSort(SortOptions.of(fn -> fn.field(q -> q.field("score").order(SortOrder.Desc))))
                .withSort(SortOptions.of(fn -> fn.field(q -> q.field("createTime").order(SortOrder.Desc))))
                .withPageable(PageRequest.of(current, limit))
                .withHighlightQuery(new HighlightQuery(new Highlight(list), DiscussPost.class))
                .build();

        SearchHits<DiscussPost> searchHits = elasticsearchTemplate.search(searchQuery, DiscussPost.class);
        // 总记录数
        map.put("totalHits", searchHits.getTotalHits());
        List<DiscussPost> discussPosts = new ArrayList<>();
        for (SearchHit<DiscussPost> searchHit : searchHits) {
            DiscussPost post = searchHit.getContent();
            // 处理高亮显示的结果
            List<String> titleHighlightField = searchHit.getHighlightField("title");
            if (titleHighlightField.size() != 0) {
                post.setTitle(titleHighlightField.get(0));
            }
            List<String> contentHighlightField = searchHit.getHighlightField("content");
            if (contentHighlightField.size() != 0) {
                post.setContent(contentHighlightField.get(0));
            }
            discussPosts.add(post);
        }
        map.put("discussPosts", discussPosts);
        return map;
    }
}